package app.biz.controller;

import app.biz.model.ClientInfo;
import app.biz.model.EcgRequest;
import app.biz.model.EcgResponse;
import app.biz.model.LogObject;
import app.biz.service.EcgResultService;
import app.biz.service.EcgRemoteService;
import app.biz.service.LogService;
import app.framework.controller.base.BaseController;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/api")
public class EcgController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(EcgController.class);

    @Autowired
    EcgRemoteService remoteService;

    @Autowired
    EcgResultService resultService;

    @Autowired
    LogService logService;

  /**
   * 接收ECG数据，调用远程AI服务解析程序
   *
   * @param fs
   * @param device_id
   * @param leads
   * @param xmlData
   * @return
   */
  @ApiOperation(
      httpMethod = "POST",
      value = "/api/v1/ecg/parse",
      notes = "# ECG XML数据解析 结果内容说明：\n"
              + "<a href=\"/lib/test1.xml.txt\">获取样例数据</a>\n"
              + "# Diagnosis class\n"
              + " 'Normal':0,\n"
              + " 'Abnormal':1,\n"
              + " 'Unknow': 2,\n"
              + "  \n"
              + "# rhythm anomoly\n"
              + "'Arrhythmia' :10,\n"
              + "'Tachycardia':11,\n"
              + "'Bradycardia':12,\n"
              + "'AFIB':13,\n"
              + "'AFL':14,\n"
              + "'VT':15,       # ventricular tachycardia\n"
              + "'SVT': 16,     # Supraventricular Tachycardia\n"
              + "'Bigeminy':17, # bigeminy\n"
              + "'Trigeminy':18,# trigeminy\n"
              + "\n"
              + "# beat anomoly\n"
              + "'LBBB':20,     # left bundle branch block beat\n"
              + "'RBBB': 21,    # right bundle branch block beat\n"
              + "'PVC': 22,     # premature ventricular contraction\n"
              + "'APC' : 23,    # atrial premature contraction\n"
              + "'VESC' : 24,   # ventricular escape beat\n"
              + "'PACE' : 25,   # paced beat\n"
              + "'ARFCT' : 26,  # isolated QRS-like artifact\n"
              + "'DEEP' : 27,   # unclasses abnormal beat\n"
              + "\n"
              + "# ST/T epocide\n"
              + "'STCH' : 30,   # ST change\n"
              + "'TCH' : 31,    # T-wave change\n"
              + "\n"
              + "# feat\n"
              + "'LVH' : 40,    # Left ventricular hypertrophy\n"
              + "'RVH' : 41,    # Right ventricular hypertrophy\n"
              + "'LAH' : 42,    # Left artria hypertrophy\n"
              + "'RAH' : 43,    # Right artria hypertrophy\n"
              + "\n"
              + "# block\n"
              + "'AVBlockI' : 50,\n"
              + "'AVBlockII' : 51,\n"
              + "'AVBlockIII' : 52,\n"
              + "        \n"
              + "# electric axis\n"
              + "'LD' : 60,     # Left deviation\n"
              + "'RD' : 61,     # Right deviation\n"
              + "'CCD' : 62,    # Counter clock direction\n"
              + "'CD' : 63,     # Clockwise direction\n"
              + "\n"
              + "# low voltage\n"
              + "'LLV' : 70,    # Limb low voltage\n"
              + "'CLV' : 71,    # Chest low voltage\n"
              + "\n"
              + "# Morphological\n"
              + "'abRinter' : 80,\n"
              + "'abPRinter': 81,\n"
              + "'abQTinter': 82,\n"
              + "'abQ' : 83\n")
  @ApiImplicitParams({
          @ApiImplicitParam(name = "fs", value = "采样率：前只支持500和1000", example = "500",allowableValues = "500,1000", required = true, dataType = "Long"),
          @ApiImplicitParam(name = "leads", value = "导联数：目前支持12导联", required = true, allowableValues = "12", example = "12", dataType = "Long"),
          @ApiImplicitParam(name = "device_id", value = "设备ID：目前支持0,1,2", example = "0", allowableValues = "0,1,2", required = true, dataType = "Long"),
          @ApiImplicitParam(name = "async", value = "异步标识：true 时为异步请求，需要稍后通过当前请求返回的SID调用/api/v1/ecg/query/{sid} 接口查询正确的返回结果", example = "false", allowableValues = "false,true", dataType = "Boolean")})
  @PostMapping(value = "/v1/ecg/parse/fs/{fs}/leads/{leads}/device_id/{device_id}/async/{async}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  public JSONObject parseEcg(
          @PathVariable  int fs,
          @PathVariable  int device_id,
          @PathVariable  int leads,
          @PathVariable  String async,
          @ApiParam(value = "心电xml数据：符合ECG格式的心电XML数据", required = true)
          @RequestBody String xmlData,
          HttpServletRequest request) {
      //装填数据
      EcgRequest ecgObj = EcgRequest.instance
                .setFs(fs)
                .setDevice_id(device_id)
                .setLeads(leads)
                .setXmlData(xmlData);
      //数据校验（除XML外）
      ecgObj.validate();
      //生成请求唯一id
      long sid = sequencer.getId();
      //记录客户端信息
      ClientInfo clientInfo = new ClientInfo()
              .setIP(request.getRemoteHost())
              //记录真IP(需要负载均衡器配合支持)
              .setRealIP(request.getHeader("X-real-ip"));

      //记录业务日志
      //TODO:LogObject貌似没啥存在的必要！
      logService.bizlog(new LogObject(sid,ecgObj),clientInfo);
      JSONObject result;
      try {
          //异步调用
          if(async!=null && "true".equals(async.toLowerCase())){
              remoteService.getAndSaveResult(sid,ecgObj);
              return EcgResponse.instance.success(sid);
          }
          //同步调用
          String resultStr = remoteService.getResult(ecgObj);
          result = EcgResponse.instance.success(sid, resultStr);
          //记录返回结果
          resultService.saveResultAsync(result);
      } catch (Exception e) {
          logger.error("", e);
          return EcgResponse.instance.falure(e);
      }
      return  result;
    }

    @ApiOperation(
            httpMethod = "GET",
            value = "/api/v1/ecg/query/{sid}",
            notes = "# 根据ID查询ECG XML解析结果")
    @GetMapping("/v1/ecg/query/{sid}")
    public JSONObject query(
            @ApiParam(value = "请求提交返回的SID", required = true)
            @PathVariable long sid) {
        return resultService.findResultBySid(sid);
    }
}
